import * as http from 'http';
import * as path from 'path';
import * as Url from 'url';
import { ip } from 'address';
import { ChildProcess } from 'child_process';
import { notFound, getPort, getHookData } from './helper/http';
import Worker from './worker';
import { logError } from './helper/utils';

export interface IOptions {
  /** 进程标识 */
  id?: string;
  /** 项目所在的根目录 */
  dir: string;
  /** webhook设置的秘钥 */
  secret: string;
  /** 端口 */
  port?: number;
  username?: string;
  password?: string;
  path?: string;
  cmd?: string;
  /** 
   * 是否启用常驻进程和守护进程
   * 该参数只在cli生效
   */
  daemon?: boolean;
}

export default async (options: IOptions): Promise<ChildProcess | null> => {
  if (!options.dir) {
    await logError('start', 'error', '缺少dir参数');
    return null;
  }
  if (!path.isAbsolute(options.dir)) {
    await logError('start', 'error', 'dir参数必须是绝对路径');
    return null;
  }

  const DIR = options.dir;
  const SECRET = options.secret;
  const PORT = await getPort(options.port);
  const WORKER = Worker();
  const URL_PATH = options.path || '/webhook';

  http.createServer(async (req, res) => {
    try {
      if (req.method !== 'POST' || Url.parse(req.url || '').pathname !== URL_PATH) return notFound(res);

      const result = await getHookData(req, SECRET);
      if (result.status) {
        const body = result.body;
        const repo = body.repository;
        const repoName = repo.name;
        // gitlab的属性名为 git_http_url 和 git_ssh_url
        const httpUrl = repo.clone_url || repo.git_http_url;
        const sshUrl = repo.ssh_url || repo.git_ssh_url;
        const tag = body.ref.match(/(v(\d+\.)+\d+)$/)[1];
        WORKER.send({
          options: { ...options, httpUrl, sshUrl },
          REPO_NAME: repoName,
          TAG: tag,
          REPO_ROOT: DIR,
          ROOT: __dirname,
        });
        res.statusCode = 200;
        res.end('successed.');
        return;
      }
      res.end('ok');
    } catch (err) {
      notFound(res, err.message);
    }
  })
    .listen(PORT)
    .on('listening', async () => {
      const info = ['Webhook配置的地址：',
        `局域网： http://${ip()}:${PORT}${URL_PATH}`,
        `外网：   http://[外网ip]:${PORT}${URL_PATH}`].join('\n');
      if (options.daemon && process.send) {
        process.send(info);
      } else {
        console.log(info);
      }
    })
    .on('error', console.error);
  return WORKER;
}
